home *** CD-ROM | disk | FTP | other *** search
- /*
-
- pcx.c
-
- Internet: alexad3@icebox.iceonline.com
- Copyright 1995, April 6 by Alec Russell, ALL rights reserved
- Permission granted to use this code as anyone wishes.
-
- Created - 1995/4/6
-
- History:
- New file
-
- Originally programmed for medium mem model, thus the liberal
- lacing of FAR * throughout the code.
-
- */
-
- #include <stdio.h>
- #include <string.h>
-
- #include <xfileio.h>
- #include <gmalloc.h>
-
-
- // for all pcx files (far as I know)
- typedef struct
- {
- char manu; /// usually 10
- char version;
- char encoding;
- char bits_per_pixel;
- int xmin, ymin, xmax, ymax;
- int hres, yres;
- char palette[48]; // not used by 256 color pcx
- char reserved;
- char color_planes;
- int bytes_per_line;
- int palette_type;
- char spare[58];
- }
- pcx_head_t;
-
-
- #define PAL_SIZE 768
- #define PCX_HD_SIZE 128
-
- /* for 256 color PC images ONLY, works with dpaint images
- Make sure b is big enough for unpacked image.
- Don't use this to get ideas for compression as
- there are much better ways to do even simple RLE encoding.
- */
- /* ---------------------- unpack_pcx() ------------------ January 4,1995 */
- int unpack_pcx(char *fname, unsigned char far *b, unsigned char *pal,
- int *p_width, int *p_height)
- {
- int err=0, i;
- unsigned int size;
- pcx_head_t pcx;
- unsigned char far *t1, far *raw;
-
- raw=far_load(fname); // load the whole file into mem,
- // an easy function to write
-
- size=load_size; // load_size is a global set by far_load()
- // if not obvious load_size is file size
- if ( raw )
- {
- if ( size > PCX_HD_SIZE )
- {
- _fmemcpy(&pcx, raw, PCX_HD_SIZE); // far memcpy
- #if 0
- // debug stuff
- pr2("manu %d", pcx.manu);
- pr2("ver %d", pcx.version);
- pr2("enc %d", pcx.encoding);
- pr2("bits %d", pcx.bits_per_pixel);
- pr2("xmin %d ymin %d xmax %d ymax %d",
- pcx.xmin, pcx.ymin, pcx.xmax, pcx.ymax);
- pr2("hres %d yres %d", pcx.hres, pcx.yres);
- pr2("rsv %d", pcx.reserved);
- pr2("planes %d", pcx.color_planes);
- pr2("bytes/line %d", pcx.bytes_per_line);
- pr2("pal type %d", pcx.palette_type);
- #endif
- // get width and height
- *p_width =pcx.xmax - pcx.xmin + 1;
- *p_height=pcx.ymax - pcx.ymin + 1;
- // get palette
- // the palette is just tacked onto the end of the file
- _fmemcpy(pal, raw+size-PAL_SIZE, PAL_SIZE);
- for ( i=0, t1=pal; i < PAL_SIZE; i++, t1++ )
- *t1>>=2;
-
- // this type of de-compression is common to most pcx files
-
- t1=raw+PCX_HD_SIZE; // skip header
- // decompress raw into b
- size-=PCX_HD_SIZE; // skip header
- size-=PAL_SIZE; // don't include palette at end
- while ( size )
- {
- if ( (*t1 & 0xc0) == 0xc0 ) // are the two high bits set?
- {
- // hi bits set, its a run
- i=*t1 & 0x3f; // mask with 00111111 to get size of run
- t1++; // next byte is color to repeat
- size--;
- while ( i-- )
- *b++=*t1;
- t1++;
- size--;
- }
- else
- {
- *b++=*t1++; // not a run, copy one byte
- size--;
- }
- }
-
- gfree(raw, "raw"); // like a free()
- }
- else
- err=2;
- }
- else
- err=1;
-
- return(err);
- }
-
- /* ------------------------------ EOF -------------------------------- */
-
-